﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.UI.WebControls;
using System.Web.UI;
using SPAdvancedSearch.Utility;

namespace SPAdvancedSearch.Editors
{
    /// <summary>
    /// Defines a base class for advanced search property value editors.
    /// </summary>
    public abstract class EditorControlBase : WebControl
    {

        #region Fields

        private Button _saveSettingsButton;
        private Button _cancelButton;
        private string _managedPropertyName;

        #endregion

        #region Events

        public delegate void SaveHandler(object sender, SaveEventArgs e);

        /// <summary>
        /// Occurs when the settings are saved.
        /// </summary>
        /// <param name="e"></param>
        public event SaveHandler Save;

        /// <summary>
        /// Raises the <see cref="Save"/> event.
        /// </summary>
        /// <param name="e"></param>
        protected void OnSave(SaveEventArgs e)
        {
            if (this.Save != null)
            {
                this.Save(this, e);
            }
        }

        #endregion

        #region Ctor

        /// <summary>
        /// Creates an instance of <see cref="EditorControlBase"/>.
        /// </summary>
        /// <param name="managedPropertyName"></param>
        protected EditorControlBase(string managedPropertyName)
        {
            _managedPropertyName = managedPropertyName;
        }

        #endregion

        #region Properties

        /// <summary>
        /// Gets the current managed property name.
        /// </summary>
        protected string ManagedPropertyName
        {
            get { return _managedPropertyName; }
        }

        /// <summary>
        /// Gets the <see cref="Button"/> responsible for canceling all changes.
        /// </summary>
        private Button CancelButton
        {
            get
            {
                if (_cancelButton == null)
                {
                    _cancelButton = new Button();
                    _cancelButton.Text = "Cancel";
                    _cancelButton.CssClass = "UserButton";
                }
                return _cancelButton;
            }
        }

        /// <summary>
        /// Gets the <see cref="Button"/> responsible for saving the settings.
        /// </summary>
        private Button SaveSettingsButton
        {
            get
            {
                if (_saveSettingsButton == null)
                {
                    _saveSettingsButton = new Button();
                    _saveSettingsButton.Text = string.Format("Save {0}", this.SaveTypeTitle);
                    _saveSettingsButton.CssClass = "UserButton";
                }

                return _saveSettingsButton;
            }
        }

        /// <summary>
        /// Allows derived classes to provide the settings for the specific control.
        /// </summary>
        public abstract string SettingsXml
        {
            get;
            set;
        }

        /// <summary>
        /// Allows derived classes to define the editor title
        /// </summary>
        protected abstract string EditorTitle
        {
            get;
        }

        /// <summary>
        /// Allows derived classes to define the save button "title".
        /// </summary>
        protected abstract string SaveTypeTitle
        {
            get;
        }

        /// <summary>
        /// Allows dervied classes to define the instructions.
        /// </summary>
        protected abstract string EditorInstructions
        {
            get;
        }

        #endregion

        #region Methods

        /// <summary>
        /// Allows specific editors to define the editor controls.
        /// </summary>
        /// <param name="controls"></param>
        protected abstract void CreateEditor(ControlCollection controls);

        /// <summary>
        /// Allows specific editors to save their settings.
        /// </summary>
        protected abstract void SaveSettings();

        /// <summary>
        /// Overridden to create the editor control.
        /// </summary>
        protected override void CreateChildControls()
        {
            this.Controls.Add(ToolPartUtility.CreateSectionHeader(this.EditorTitle));
            this.CreateEditor(this.Controls);
            this.Controls.Add(new LiteralControl("<br />"));

            this.Controls.Add(new LiteralControl(string.Format("<em>{0}</em>", this.EditorInstructions)));

            Panel panel = new Panel();
            panel.Attributes.Add("style", "text-align:right;");

            this.CancelButton.Click += new EventHandler(CancelButton_Click);
            this.SaveSettingsButton.Click += new EventHandler(SaveSettingsButton_Click);
            panel.Controls.Add(this.CancelButton);
            panel.Controls.Add(new LiteralControl("&nbsp;"));
            panel.Controls.Add(this.SaveSettingsButton);
            this.Controls.Add(panel);
        }

        #endregion

        #region Event Handlers

        /// <summary>
        /// Cancels all changes made during the current editing session.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void CancelButton_Click(object sender, EventArgs e)
        {
            this.Visible = false;
        }

        /// <summary>
        /// Responds to the event raised when the save settings button is clicked.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void SaveSettingsButton_Click(object sender, EventArgs e)
        {
            this.SaveSettings();
            SaveEventArgs args = new SaveEventArgs();
            args.SettingsXml = this.SettingsXml;
            args.ManagedPropertyName = this._managedPropertyName;

            this.OnSave(args);
        }

        #endregion

    }

    /// <summary>
    /// Represents the event data when settings are saved.
    /// </summary>
    public class SaveEventArgs : EventArgs
    {

        #region Properties

        /// <summary>
        /// Gets or sets the managed property related to the settings.
        /// </summary>
        public string ManagedPropertyName
        {
            get;
            set;
        }

        /// <summary>
        /// Gets or sets the settings xml.
        /// </summary>
        public string SettingsXml
        {
            get;
            set;
        }

        #endregion

    }
}
